﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.LIB;
using YArchitech.Revit;

namespace HYOpeningDetail
{
	internal class CenterBasedCircularComponent : CircularComponent
	{
		public new void DimBoxFunction(ElementInfo elementInfo, ViewPlan viewPlan, Dictionary<XYZ, DataWall> dicWallCurve, Dictionary<XYZ, List<Curve>> dicCombineGridCurve, Autodesk.Revit.DB.Document doc, int iBoxCategory)
		{
			this.m_doc = doc;
			Transaction transaction = new Transaction(this.m_doc, "Dim");
			try
			{
				transaction.Start();
				if (OpeningViewDataSetForm.BRadSelGrid)
				{
					this.CreateLocationDimensionByGridCurve(elementInfo, viewPlan, dicCombineGridCurve);
				}
				else
				{
					this.CreateLocationDimensionByWallCurve(elementInfo, viewPlan, dicWallCurve);
				}
				if (iBoxCategory == 4)
				{
					this.CreateLeaderDimension(elementInfo, viewPlan, iBoxCategory);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private bool CreateLocationDimensionByGridCurve(ElementInfo elementInfo, ViewPlan viewPlan, Dictionary<XYZ, List<Curve>> dicCombineGridCurve)
		{
			XYZ ptFamInstance = null;
			FamilyInstance familyInstance = elementInfo.element as FamilyInstance;
			LocationPoint locationPoint = familyInstance.Location as LocationPoint;
			Transform transform = null;
			if (elementInfo.revitLink != null)
			{
				transform = elementInfo.revitLink.GetTransform();
				ptFamInstance = transform.OfPoint(locationPoint.Point);
			}
			else
			{
				ptFamInstance = locationPoint.Point;
			}
			XYZ xyz = null;
			dicCombineGridCurve = (from k in dicCombineGridCurve
			orderby k.Key.DistanceTo(ptFamInstance)
			select k).ToDictionary((KeyValuePair<XYZ, List<Curve>> k) => k.Key, (KeyValuePair<XYZ, List<Curve>> k) => k.Value);
			if (dicCombineGridCurve.Count > 0)
			{
				xyz = dicCombineGridCurve.ElementAt(0).Key;
				List<Curve> value = dicCombineGridCurve.ElementAt(0).Value;
				List<Curve> list = new List<Curve>();
				this.GetNewGridInfo(ref xyz, value, ref list, ptFamInstance);
				bool flag = this.IsGridIntersecctFace(value[0], familyInstance, transform);
				bool flag2 = this.IsGridIntersecctFace(value[1], familyInstance, transform);
				if (!flag && !flag2)
				{
					XYZ project = new YJKCurve(list[0]).GetProject(ptFamInstance, false);
					XYZ project2 = new YJKCurve(list[1]).GetProject(ptFamInstance, false);
					XYZ vectorMove = project.Subtract(xyz).Normalize();
					XYZ vectorMove2 = project2.Subtract(xyz).Normalize();
					Line dimNewLine = Line.CreateBound(project, ptFamInstance);
					base.CreateDetailLine(project, ptFamInstance, vectorMove, viewPlan, dimNewLine, false);
					Line dimNewLine2 = Line.CreateBound(ptFamInstance, project2);
					base.CreateDetailLine(ptFamInstance, project2, vectorMove2, viewPlan, dimNewLine2, false);
				}
				if ((flag && !flag2) || (!flag && flag2))
				{
					Curve curve = null;
					Curve curve2 = null;
					if (this.IsGridIntersecctFace(list[0], familyInstance, transform))
					{
						curve = list[1];
						curve2 = list[0];
					}
					if (this.IsGridIntersecctFace(list[1], familyInstance, transform))
					{
						curve = list[0];
						curve2 = list[1];
					}
					XYZ project3 = new YJKCurve(curve).GetProject(ptFamInstance, false);
					new YJKCurve(curve2).GetProject(ptFamInstance, false);
					XYZ vectorMove3 = (curve as Line).Direction.Normalize();
					Line dimNewLine3 = Line.CreateBound(project3, ptFamInstance);
					base.CreateDetailLine(project3, ptFamInstance, vectorMove3, viewPlan, dimNewLine3, false);
				}
				return !flag || !flag2;
			}
			return false;
		}

		private bool CreateLocationDimensionByWallCurve(ElementInfo elementInfo, ViewPlan viewPlan, Dictionary<XYZ, DataWall> dicWallCurve)
		{
			XYZ ptFamInstance = null;
			LocationPoint locationPoint = (elementInfo.element as FamilyInstance).Location as LocationPoint;
			if (elementInfo.revitLink != null)
			{
				Transform transform = elementInfo.revitLink.GetTransform();
				ptFamInstance = transform.OfPoint(locationPoint.Point);
			}
			else
			{
				ptFamInstance = locationPoint.Point;
			}
			dicWallCurve = (from k in dicWallCurve
			orderby k.Key.DistanceTo(ptFamInstance)
			select k).ToDictionary((KeyValuePair<XYZ, DataWall> k) => k.Key, (KeyValuePair<XYZ, DataWall> k) => k.Value);
			if (dicWallCurve.Count > 0)
			{
				DataWall value = dicWallCurve.ElementAt(0).Value;
				XYZ key = dicWallCurve.ElementAt(0).Key;
				double dFirstWallWidth = value.dFirstWallWidth;
				XYZ project = new YJKLine(value.curvrFirst as Line).GetProject(ptFamInstance);
				XYZ xyz = ptFamInstance.Subtract(project).Normalize();
				XYZ xyz2 = project.Add(xyz * 0.5 * dFirstWallWidth);
				double dSecondWallWidth = value.dSecondWallWidth;
				XYZ project2 = new YJKLine(value.curveSecond as Line).GetProject(ptFamInstance);
				XYZ xyz3 = ptFamInstance.Subtract(project2).Normalize();
				XYZ xyz4 = project2.Add(xyz3 * 0.5 * dSecondWallWidth);
				Line dimNewLine = Line.CreateBound(ptFamInstance, xyz2);
				base.CreateDetailLine(ptFamInstance, xyz2, xyz3, viewPlan, dimNewLine, false);
				Line dimNewLine2 = Line.CreateBound(xyz4, ptFamInstance);
				base.CreateDetailLine(ptFamInstance, xyz4, xyz, viewPlan, dimNewLine2, false);
				return true;
			}
			return false;
		}

		private new void CreateLeaderDimension(ElementInfo dicElementInfo, ViewPlan viewPlan, int iBoxCategory)
		{
			LocationPoint locationPoint = (dicElementInfo.element as FamilyInstance).Location as LocationPoint;
			XYZ xyz;
			if (dicElementInfo.revitLink != null)
			{
				xyz = dicElementInfo.revitLink.GetTransform().OfPoint(locationPoint.Point);
			}
			else
			{
				xyz = locationPoint.Point;
			}
			string strLevelText = null;
			string strFamText = null;
			this.GetDimText(dicElementInfo, iBoxCategory, ref strLevelText, ref strFamText);
			XYZ xyz2 = xyz;
			XYZ ptDimPosionFir = new XYZ(xyz2.X + NumbericTools.mmToFeet(800.0), xyz2.Y - NumbericTools.mmToFeet(400.0), xyz2.Z);
			base.LeaderDimension(xyz2, ptDimPosionFir, strFamText, strLevelText, viewPlan);
		}

		private void GetDimText(ElementInfo dicElementInfo, int iBoxCategory, ref string strLevelText, ref string strFamText)
		{
			FamilyInstance familyInstance = dicElementInfo.element as FamilyInstance;
			double value = 0.0;
			double value2 = 0.0;
			Parameter parameter = base.GetParameter(familyInstance, "半径");
			Parameter parameter2 = base.GetParameter(familyInstance, "深度");
			if (parameter != null)
			{
				value = NumbericTools.feetTomm(parameter.AsDouble());
			}
			if (parameter2 != null)
			{
				value2 = NumbericTools.feetTomm(parameter2.AsDouble());
			}
			string str = "半径" + Convert.ToInt32(value).ToString();
			string str2 = "深度" + Convert.ToInt32(value2).ToString();
			familyInstance.Symbol.Family.Name.ToString();
			strFamText = "集水坑";
			strLevelText = str + "," + str2;
		}

		public new bool GetFaceCurve(Face face, ref List<Curve> lstCurve)
		{
			EdgeArrayArray edgeLoops = face.EdgeLoops;
			if (edgeLoops.Size < 1)
			{
				return false;
			}
			foreach (object obj in edgeLoops)
			{
				EdgeArray edgeArray = (EdgeArray)obj;
				if (edgeArray.Size >= 1)
				{
					foreach (object obj2 in edgeArray)
					{
						Curve item = ((Edge)obj2).AsCurve();
						lstCurve.Add(item);
					}
				}
			}
			return lstCurve.Count >= 1;
		}

		public bool IsGridIntersecctFace(Curve curGrid, FamilyInstance familyInstance, Transform transformToDoc)
		{
			Transform transform = familyInstance.GetTransform();
			List<Face> list = new List<Face>();
			PublicFunction.GetAllFace(familyInstance, ref list, XYZ.BasisZ, null);
            //from i in list
            //orderby -i.Area
            //select i;
			if (list.Count < 1)
			{
				return false;
			}
			Face face = list[list.Count - 1];
			List<Curve> list2 = new List<Curve>();
			if (!this.GetFaceCurve(face, ref list2))
			{
				return false;
			}
			if (transformToDoc != null)
			{
				foreach (Curve curve in list2)
				{
					Curve otherCurve = curve.CreateTransformed(transform).CreateTransformed(transformToDoc);
					if (new YJKCurve(Line.CreateBound(new XYZ(curGrid.GetEndPoint(0).X, curGrid.GetEndPoint(0).Y, curve.GetEndPoint(0).Z), new XYZ(curGrid.GetEndPoint(1).X, curGrid.GetEndPoint(1).Y, curve.GetEndPoint(1).Z))).IntersectionAllPoint(otherCurve).Count > 0)
					{
						return true;
					}
				}
				return false;
			}
			List<XYZ> list3 = null;
			foreach (Curve curve2 in list2)
			{
				Curve otherCurve2 = curve2.CreateTransformed(transform);
				list3 = new YJKCurve(Line.CreateBound(new XYZ(curGrid.GetEndPoint(0).X, curGrid.GetEndPoint(0).Y, curve2.GetEndPoint(0).Z), new XYZ(curGrid.GetEndPoint(1).X, curGrid.GetEndPoint(1).Y, curve2.GetEndPoint(1).Z))).IntersectionAllPoint(otherCurve2);
			}
			if (list3.Count > 0)
			{
				return true;
			}
			return false;
		}

		private void GetNewGridInfo(ref XYZ ptGridIntersect, List<Curve> lstGridCurve, ref List<Curve> lstNewGridCurve, XYZ ptFamInstance)
		{
			ptGridIntersect = new XYZ(ptGridIntersect.X, ptGridIntersect.Y, ptFamInstance.Z);
			foreach (Curve curve in lstGridCurve)
			{
				Line item = Line.CreateBound(new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, ptFamInstance.Z), new XYZ(curve.GetEndPoint(1).X, curve.GetEndPoint(1).Y, ptFamInstance.Z));
				lstNewGridCurve.Add(item);
			}
		}
	}
}
